<template>
    <div ref="container" class="container" :style="{
        overflowY: 'auto',
        height: `${containerHeight}px`,
        position: 'relative'
    }" @scroll="handleScroll">
        <!-- 占位元素，用于撑开滚动条 -->
        <div :style="{ height: `${itemHeight * props.list.length}px` }"></div>
        <!-- 可视区域，通过 transform 偏移 -->
        <div ref="vlist" :style="{
            position: 'absolute',
            top: '0',
            left: '0',
            right: '0',
            transform: `translateY(${offset}px)`
        }">
            <ul style="list-style: none; padding: 0; margin: 0">
                <li v-for="(item, index) in dataList" :key="index" :style="{
                    height: `${itemHeight}px`,
                    padding: '5px',
                    borderBottom: '1px solid #eee'
                }">
                    {{ item }}
                </li>
            </ul>
        </div>
    </div>
</template>

<script lang="ts" setup>
import { computed, onMounted, ref } from 'vue'
import _ from 'lodash'

const props = defineProps<{
    list: string[]
}>()

const container = ref<HTMLDivElement | null>(null)
const vlist = ref<HTMLDivElement | null>(null)
const containerHeight = ref(0)
const itemHeight = 30// 列表元素的高度
const startIndex = ref(0) // 截取开始的索引
const endIndex = ref(0)  // 截取结束的索引，计算出来， 容器的高度/ 单条数据的高度 + startIndex
const pageItems = ref(0)
const offset = ref(0)

const handleScroll = _.throttle(() => {
    if (!container.value) return
    const scrollTop = container.value.scrollTop
    const newStartIndex = Math.floor(scrollTop / itemHeight)
    // 限制 startIndex 在合理范围内
    startIndex.value = Math.max(0, newStartIndex)
    endIndex.value = Math.min(startIndex.value + pageItems.value, props.list.length)
    if (endIndex.value < props.list.length - 1) {
        endIndex.value += 1;
    }
    // 更新偏移量
    offset.value = startIndex.value * itemHeight
}, 16) // 使用 16ms（约 60fps）的节流时间
onMounted(() => {
    if (container.value) {
        containerHeight.value = container.value.parentElement?.offsetHeight as number
        pageItems.value = Math.ceil(containerHeight.value / itemHeight)
        endIndex.value = pageItems.value
    }
})

const dataList = computed(() => props.list.slice(startIndex.value, endIndex.value + 1))
</script>

<style>
.container {}
</style>